﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using RPG;

namespace LatinKid
{
    class Animation : Microsoft.Xna.Framework.DrawableGameComponent
    {
        Game GAME;

        public Rectangle CurrentRect;

        Texture2D Texture;
        List<Texture2D> Textures;

        List<Rectangle> FrameRectangles;

        Keys TriggerKey;

        SpriteEffects Effect;

        public Vector2 Position;

        private int FPS;
        public int FrameCount { get; set; }
        private int Frames;

        KeyboardState kstate;

        Color Color;

        ConstructorType ConstructerType;

        enum ConstructorType
        {
            WithKeyNoEffect,
            WithKeyAndEffect,
            NoKeyWithEffect
        }

        /// <summary>
        /// Creates a new instance of Animation class
        /// </summary>
        /// <param name="game">If your doing this in Game1.cs, type this, if not, point to it through a variable</param>
        /// <param name="imageName">This class will automatically load up the texture, just tell it the file name</param>
        /// <param name="key">When this key is pressed, it will activate the animation (Not implemented yet, but is still used for TriggerKeyIsPressed)</param>
        /// <param name="inFPS">Frames per second</param>
        public Animation(Game game, string imageName, Keys key, int inFPS)
            : base(game)
        {
            ConstructerType = ConstructorType.WithKeyNoEffect;
            GAME = game;
            Texture = GAME.Content.Load<Texture2D>(imageName);
            TriggerKey = key;
            FPS = inFPS;
            Frames = 0;
            Effect = SpriteEffects.None;
            FrameRectangles = new List<Rectangle>();
            CurrentRect = new Rectangle();
            Color = Color.White;
            Position = new Vector2();
        }

        /// <summary>
        /// Creates a new instance of Animation class
        /// </summary>
        /// <param name="game">If your doing this in Game1.cs, type this, if not, point to it through a variable</param>
        /// <param name="imageName">This class will automatically load up the texture, just tell it the file name</param>
        /// <param name="key">When this key is pressed, it will activate the animation (Not implemented yet, but is still used for TriggerKeyIsPressed)</param>
        /// <param name="inFPS">Frames per second</param>
        public Animation(Game game, string imageName, Keys key, int inFPS, SpriteEffects effect)
            : base(game)
        {
            ConstructerType = ConstructorType.WithKeyAndEffect;
            GAME = game;
            Texture = GAME.Content.Load<Texture2D>(imageName);
            TriggerKey = key;
            FPS = inFPS;
            Frames = 0;
            Effect = effect;
            FrameRectangles = new List<Rectangle>();
            CurrentRect = new Rectangle();
            Color = Color.White;
        }

        /// <summary>
        /// Creates a new instance of Animation class
        /// </summary>
        /// <param name="game">If your doing this in Game1.cs, type this, if not, point to it through a variable</param>
        /// <param name="imageName">This class will automatically load up the texture, just tell it the file name</param>
        /// <param name="key">When this key is pressed, it will activate the animation (Not implemented yet, but is still used for TriggerKeyIsPressed)</param>
        /// <param name="inFPS">Frames per second</param>
        public Animation(Game game, string imageName, int inFPS, SpriteEffects effect, Color color)
            : base(game)
        {
            ConstructerType = ConstructorType.NoKeyWithEffect;
            GAME = game;
            Texture = GAME.Content.Load<Texture2D>(imageName);
            FPS = inFPS;
            Frames = 0;
            Effect = effect;
            FrameRectangles = new List<Rectangle>();
            CurrentRect = new Rectangle();
            Color = color;
        }

        /// <summary>
        /// Manually add a frame. According to the arguments passed, it will create a rectangle according to the texture used in this object.
        /// </summary>
        /// <param name="x">X coordinate (starting point on X axis)</param>
        /// <param name="y">Y coordinate (ditto)</param>
        /// <param name="w">Width of your desired frame</param>
        /// <param name="h">Height of your desired frame</param>
        public void AddFrame(int x, int y, int w, int h)
        {
            FrameRectangles.Add(new Rectangle(x, y, w, h));
            Frames++;
        }

        /// <summary>
        /// Will try to guess the frames in the texture loaded. Will ONLY WORK if ALL FRAMES are of SAME WIDTH and HEIGHT.
        /// </summary>
        /// <param name="FramesPerRow">How many frames are in each row?</param>
        /// <param name="FramesPerColumn">How many frames are in each column?</param>
        public void GuessFrames(int FramesPerRow, int FramesPerColumn)
        {
            int FrameHeight = 0;
            int FrameWidth = 0;

            FrameWidth = Texture.Width / FramesPerRow;
            FrameHeight = Texture.Height / FramesPerColumn;


            //Will iterate until hIt (heightIterator) is no longer in range of Texture.Height, and same for hIt)
            for (int hIt = 0; hIt <= Texture.Height; hIt += FrameHeight)
            {
                for (int wIt = 0; wIt <= Texture.Width; wIt += FrameWidth)
                {
                    FrameRectangles.Add(new Rectangle(wIt, hIt, FrameWidth, FrameHeight));
                    Frames++;
                }
            }
        }

        public override void Initialize()
        {
            CurrentRect = new Rectangle();
            base.Initialize();
        }

        protected override void LoadContent()
        {
            base.LoadContent();
        }

        /// <summary>
        /// Compares the trigger key to what keys are pressed
        /// </summary>
        /// <returns>Will return true if the trigger key is pressed down. Will return false if the trigger key is not pressed down</returns>
        public bool TriggerKeyIsPressed()
        {
            if (kstate.IsKeyDown(TriggerKey))
                return true;

            else
                return false;
        }

        /// <summary>
        /// Runs the animation. Frame count is always set to 0 when the trigger key is not pressed (checked inside Update), and will do some magic (actually just simple math)
        /// and according to FPS and FrameCount, will Draw certain rectangles at certain times.
        /// </summary>
        /// <param name="position">The position you want the frame at</param>
        public void RunAnimation(Vector2 position)
        {
            for (int i = 0; i <= FrameRectangles.Count(); i++)
            {
                if (FrameCount == (FPS * i) && (FrameCount != (Frames * FPS)))
                {
                    CurrentRect = FrameRectangles[i];
                    break;
                }

                else if (FrameCount > (Frames * FPS))
                {
                    FrameCount = 0;
                    break;
                }
            }

            Position.X = position.X;
            Position.Y = position.Y;

            FrameCount++;

            GAME.spriteBatch.Begin();
            GAME.spriteBatch.Draw(Texture, position, CurrentRect, Color, 0, Vector2.Zero, 2.5f, Effect, 1f);
            GAME.spriteBatch.End();
        }

        public override void Update(GameTime gameTime)
        {
            kstate = Keyboard.GetState();

            if ((!(TriggerKeyIsPressed())) && ConstructerType != ConstructorType.NoKeyWithEffect)
                FrameCount = 0;

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)// Is this necessary? Idts
        {
            base.Draw(gameTime);
        }
    }
}


